#ifndef _TOMO_FFT_H_
#define _TOMO_FFT_H_

#include "amdspl.h"
#include "CommonDefs.h"
#include "ProgramInfo.h"
#include "BufferManager.h"
#include "ProgramManager.h"
#include "CounterManager.h"
#include "DeviceManager.h"
#include "VectorDataType.h"
#include "DataTransManager.h"

using namespace amdspl;
using namespace amdspl::core::cal;

class TomoFFT
{
public:
    TomoFFT(void);
    ~TomoFFT(void);

    bool initialize(unsigned short id = 0);

    bool FFT8(float2 *data, unsigned int size);
    bool FFT16(float2 *data, unsigned int size);
    bool FFT32(float2 *data, unsigned int size);
    bool FFT64(float2 *data, unsigned int size);
    bool FFT256(float2 *data, unsigned int size);
    bool FFT512(float2 *data, unsigned int size);
    bool FFT1024(float2 *data, unsigned int size);
    bool FFT2048(float2 *data, unsigned int size);
    bool FFT2048NT(float2 *data, unsigned int size);

    bool IFFT8(float2 *data, unsigned int size);
    bool IFFT16(float2 *data, unsigned int size);
    bool IFFT64(float2 *data, unsigned int size);
    bool IFFT512(float2 *data, unsigned int size);
    bool IFFT1024(float2 *data, unsigned int size);
    bool IFFT2048(float2 *data, unsigned int size);
    bool IFFT2048NT(float2 *data, unsigned int size);

    void transpose( float2 *dst, float2 *src, int num, int sz, int sy, int sx );

    bool filter2048(Buffer *buffer, const unsigned int height);
    
    bool compute2048_5step(Buffer *buffer, const unsigned int height);
    

    bool bindBuffer2048(LocalBuffer *buffer, ConstBuffer *filter_buffer);
    bool compute2048(const unsigned int height);

    bool simplecompute(const unsigned int height);

    Buffer* input512_2048(float* ptr, unsigned int n);

    DataTransManager *_dataMgr;


private:    
    void paddingData(float4 *dst, float2* src, int padedSize);
    void unpaddingData(float2 *dst, float4* src, int padedSize);
	bool dataInput(float2 * data, unsigned int padedSize, unsigned int width, unsigned int height,  Buffer * gBuf, uint4 * transParam);
	bool dataOutput(float2 * data, unsigned int padedSize, unsigned int width, unsigned int height,  Buffer * gBuf, uint4 * transParam);

    Runtime*        _runtime;
    ProgramManager* _progMgr;
    BufferManager*  _bufMgr;
    DeviceManager*  _devMgr;
    CounterManager*  _cntMgr;

    ProgramInfo _fft8ProgInfo;
    ProgramInfo _fft16ProgInfo;
    ProgramInfo _fft32ProgInfo;
    ProgramInfo _fft64ProgInfo;
    ProgramInfo _fft256ProgInfo;
    ProgramInfo _fft512ProgInfo;
    ProgramInfo _fft1024ProgInfo;
    ProgramInfo _fft2048_fft4ProgInfo;

    ProgramInfo _ifft8ProgInfo;
    ProgramInfo _ifft16ProgInfo;
//    ProgramInfo _ifft32ProgInfo;
    ProgramInfo _ifft64ProgInfo;
    ProgramInfo _ifft512ProgInfo;
    ProgramInfo _ifft1024ProgInfo;
    ProgramInfo _ifft2048_fft4ProgInfo;
    ProgramInfo _ifft2048_fft4_ntProgInfo;

    ProgramInfo _transpose2048ProgInfo;

    ProgramInfo _filter2048CSProgInfo;
    ProgramInfo _filter2048PSProgInfo;
    ProgramInfo    simple_computeProgInfo;

	ProgramInfo _fftInputProgInfo;
	ProgramInfo _fftOutputProgInfo;
	ProgramInfo _fftOutput5DProgInfo;

    Program*    _fft8Prog;
    Program*    _fft16Prog;
    Program*    _fft32Prog;
    Program*    _fft64Prog;
    Program*    _fft256Prog;
    Program*    _fft512Prog;
    Program*    _fft1024Prog;
    Program*    _fft2048_fft4Prog;

    Program*    _ifft8Prog;
    Program*    _ifft16Prog;
    Program*    _ifft64Prog;
    Program*    _ifft512Prog;
    Program*    _ifft1024Prog;
    Program*    _ifft2048_fft4Prog;
    Program*    _ifft2048_fft4_ntProg;

    Program*    _transpose2048Prog;

    Program*    _filter2048CSProg;
    Program*    _filter2048PSProg;
    Program*    _simple_compute_Prog;

	Program*	_fftInputProg;
	Program*	_fftOutputProg;
	Program*	_fftOutput5DProg;
};

#endif // _TOMO_FFT_H_